/** Description of GraphToday.java 
 *
 * @author panther
 * Jayant Pratim Saikia
 * jay.saikia@gmail.com
 *
 */
package com.panther.awp.android.smoker.activities.graphs;

import java.text.FieldPosition;
import java.text.Format;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import android.app.Activity;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import com.androidplot.Plot;
import com.androidplot.ui.AnchorPosition;
import com.androidplot.ui.DynamicTableModel;
import com.androidplot.ui.SizeLayoutType;
import com.androidplot.ui.SizeMetrics;
import com.androidplot.ui.widget.DomainLabelWidget;
import com.androidplot.xy.BarFormatter;
import com.androidplot.xy.BarRenderer;
import com.androidplot.xy.BoundaryMode;
import com.androidplot.xy.SimpleXYSeries;
import com.androidplot.xy.XLayoutStyle;
import com.androidplot.xy.XYLegendWidget;
import com.androidplot.xy.XYPlot;
import com.androidplot.xy.XYStepMode;
import com.androidplot.xy.YLayoutStyle;
import com.panther.awp.android.smoker.R;
import com.panther.awp.android.smoker.database.AbstractDbAdapter;
import com.panther.awp.android.smoker.database.MyDBWrapper;

public class GraphToday extends Activity {
	
	private XYPlot mPriceBarPlot;
	private MyDBWrapper mDBWrapper;
	private TextView myCountText;
	private int totalCount = 0;
	private float totalCost = 0f;
	private HashMap<Number, Date> ciggIdHMap;
	private HashMap<Long, HashMap<Number, Number>> brandWiseHMap;
	private float lowerlimitCost = Float.MAX_VALUE;
	private float upperlimitCost = 0f;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.todayplot);
		mDBWrapper = MyDBWrapper.getInstance(getApplicationContext());
		mPriceBarPlot = (XYPlot) findViewById(R.id.myTodayBarPricePlot);
		myCountText = (TextView) findViewById(R.id.total_Smoked_Cigs);
		getData();
		addDynamicSeries();
		setPlotProperties();
		myCountText.setText("You have smoked " + totalCount + " cigarettes and it has cost you " + totalCost + " bucks.");
	}

	private void setPlotProperties() {
		
		//mPriceBarPlot.getGraphWidget().getGridBackgroundPaint().setColor(Color.WHITE);
		mPriceBarPlot.getGraphWidget().getGridLinePaint().setColor(Color.BLACK);
		mPriceBarPlot.getGraphWidget().getGridLinePaint().setPathEffect(new DashPathEffect(new float[]{1,1}, 1));
		mPriceBarPlot.getGraphWidget().getDomainOriginLinePaint().setColor(Color.BLACK);
		mPriceBarPlot.getGraphWidget().getRangeOriginLinePaint().setColor(Color.BLACK);
        
        if(ciggIdHMap.size() == 1) {
			mPriceBarPlot.setDomainBoundaries(0, 2, BoundaryMode.FIXED);
		}
        
        mPriceBarPlot.setDomainStep(XYStepMode.INCREMENT_BY_VAL, 1);
        mPriceBarPlot.setTicksPerRangeLabel(4);
        mPriceBarPlot.setRangeBoundaries(lowerlimitCost == 0 ? 0 : lowerlimitCost - 1, upperlimitCost + 1, BoundaryMode.FIXED);
        //mPriceBarPlot.setDomainBoundaries(0, 24*60*60, BoundaryMode.FIXED);
        mPriceBarPlot.setDomainValueFormat(new BrandIndexFormat());
        mPriceBarPlot.setDomainLabel("Time -->");
        mPriceBarPlot.getDomainLabelWidget().pack();
        mPriceBarPlot.setRangeLabel("");
        mPriceBarPlot.getRangeLabelWidget().pack();
        mPriceBarPlot.setGridPadding(10, 0, 10, 0);
        mPriceBarPlot.setPlotMargins(0, 0, 0, 0);
		mPriceBarPlot.setPlotPadding(0, 0, 0, 10);
        mPriceBarPlot.getGraphWidget().setMarginTop(2);
        mPriceBarPlot.getGraphWidget().setMarginRight(2);
        mPriceBarPlot.setBorderStyle(Plot.BorderStyle.SQUARE, null, null);
        mPriceBarPlot.disableAllMarkup();
		
		BarRenderer barRendererPrice = (BarRenderer) mPriceBarPlot.getRenderer(BarRenderer.class);
        if(barRendererPrice != null) {
            // make our bars a little thicker than the default so they can be seen better:
        	barRendererPrice.setBarWidth(10);
        }
	
		DomainLabelWidget domainLabelWidget = mPriceBarPlot.getDomainLabelWidget();
		mPriceBarPlot.position(domainLabelWidget, 30, XLayoutStyle.ABSOLUTE_FROM_LEFT, -10, YLayoutStyle.ABSOLUTE_FROM_BOTTOM, AnchorPosition.LEFT_BOTTOM);
		
		XYLegendWidget legendWidget = mPriceBarPlot.getLegendWidget();
		if(brandWiseHMap.size() > 4) {
			int col = (int)(brandWiseHMap.size()/2);
			legendWidget.setTableModel(new DynamicTableModel(brandWiseHMap.size()%2 == 0 ? col : ++col, 2));
		}
		legendWidget.setSize(new SizeMetrics(40, SizeLayoutType.ABSOLUTE, 60, SizeLayoutType.FILL));
		mPriceBarPlot.position(legendWidget, 0, XLayoutStyle.ABSOLUTE_FROM_CENTER, 10, YLayoutStyle.ABSOLUTE_FROM_TOP, AnchorPosition.TOP_MIDDLE);
		
	}

	private void getData() {
		Calendar cal = Calendar.getInstance();
		//cal.set(Calendar.DATE, 20);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 1);
		Date afterThisDate = new Date(cal.getTimeInMillis());
		//cal.set(Calendar.DATE, 30);
		cal.set(Calendar.HOUR_OF_DAY, 23);
		cal.set(Calendar.MINUTE, 59);
		cal.set(Calendar.SECOND, 59);
		cal.set(Calendar.MILLISECOND, 999);
		Date beforeThisDate = new Date(cal.getTimeInMillis());
		Cursor cursor = mDBWrapper.getmTTDbHelper().fetchInBetweenDate(afterThisDate, beforeThisDate);
		startManagingCursor(cursor);
		cursor.moveToFirst();
		brandWiseHMap = new HashMap<Long, HashMap<Number,Number>>();
		ciggIdHMap = new HashMap<Number, Date>();
		int barCount = 0;
		while (!cursor.isAfterLast()) {
			
			barCount++;
			float cost = cursor.getFloat(cursor.getColumnIndexOrThrow(AbstractDbAdapter.TT_COST));
			Long brandId = cursor.getLong(cursor.getColumnIndexOrThrow(AbstractDbAdapter.TT_BRAND_ID));
			String dateTimeStr = cursor.getString(cursor.getColumnIndexOrThrow(AbstractDbAdapter.TT_DATETIME));
			Date smokeDate = null;
			try {
				smokeDate = AbstractDbAdapter.DATE_FORMAT.parse(dateTimeStr);
			} catch (ParseException e) {
			}
			if(smokeDate != null) {
				
				if(brandWiseHMap.containsKey(brandId)) {
					HashMap<Number, Number> ciggPriceMap = brandWiseHMap.get(brandId);
					ciggPriceMap.put(barCount, cost);
				} else {
					HashMap<Number, Number> ciggPriceMap = new HashMap<Number, Number>();
					ciggPriceMap.put(barCount, cost);
					brandWiseHMap.put(brandId, ciggPriceMap);
				}
				
				ciggIdHMap.put(barCount, smokeDate);
				totalCount++;
				totalCost += cost;
				
				lowerlimitCost = lowerlimitCost > cost ? cost : lowerlimitCost;
				upperlimitCost = upperlimitCost < cost ? cost : upperlimitCost;
				
			} else {
				Log.w(getCallingPackage(), "Wrong Data in database or something went horribly wrong.");
			}
			
			cursor.moveToNext();
		}
		
	}

	private void addDynamicSeries() {
		for (Long brandId : brandWiseHMap.keySet()) {
			String brandName = "";
			Cursor cursor = mDBWrapper.getmBTDbHelper().fetch(brandId);
			cursor.moveToFirst();
			while(!cursor.isAfterLast()) {
				brandName = cursor.getString(cursor.getColumnIndexOrThrow(AbstractDbAdapter.BT_BRAND));
				cursor.moveToNext();
			}
			cursor.close();
			List<Number> ciggCostVals = new ArrayList<Number>(brandWiseHMap.get(brandId).values());
			List<Number> ciggIdVals = new ArrayList<Number>(brandWiseHMap.get(brandId).keySet());
			SimpleXYSeries thisBrandSeries = new SimpleXYSeries(ciggIdVals, ciggCostVals, brandName);
			int color = Color.rgb(new Double(Math.random()*255).intValue(), new Double(Math.random()*255).intValue(), new Double(Math.random()*255).intValue());
			mPriceBarPlot.addSeries(thisBrandSeries, BarRenderer.class, new BarFormatter(color, color));
		}
	}

	private class BrandIndexFormat extends Format {

		private static final long serialVersionUID = 5133698491470068632L;
		private final SimpleDateFormat outputFormat = new SimpleDateFormat("KK:mm a");

		@Override
		public StringBuffer format(Object object, StringBuffer buffer, FieldPosition field) {
			Number num = (Number) object;
			int roundNum = (int) (num.floatValue());
			if(ciggIdHMap.containsKey(roundNum)) {
				buffer.append(outputFormat.format(ciggIdHMap.get(roundNum)));
			}
			return buffer;
		}

		@Override
		public Object parseObject(String string, ParsePosition position) {
			return null;
		}
		
	}
}
